#pragma once
#include "funcbase.h"

namespace KRPC {

template<typename>
class AsyncFunc;

template<typename R, typename ... Args>
class AsyncFunc<R(Args...)> : public FuncBase
{	//针对返回参数是非void
public:
	AsyncFunc(std::string _name, COM &com) : FuncBase(com), name(std::move(_name))	
	{
		assert(name.size() < MAX_RPCNAME_LEN);
	}
		
	Result<R> operator()(Args... args)
	{
		return send(name, RPC_REQ, std::forward<Args>(args)...) \
			? Result<R>(std::bind(&FuncBase::recv<R>, this, std::placeholders::_1, RPC_REP, std::placeholders::_2)) \
			: Result<R>(nullptr);
	}
private:
	std::string name;
};

template<typename ... Args>
class AsyncFunc<void(Args...)> : public FuncBase
{	//针对返回参数是void
public:
	AsyncFunc(std::string _name, COM &com) : FuncBase(com), name(std::move(_name))	
	{
		assert(name.size() < MAX_RPCNAME_LEN);
	}

	Result<void> operator()(Args... args)
	{
		return send(name, RPC_REQ, std::forward<Args>(args)...) \
			? Result<void>(std::bind((bool (FuncBase::*)(MsgMode, int)) &FuncBase::recv, this, RPC_REP, std::placeholders::_1)) \
			: Result<void>(nullptr);
	}
private:
	std::string name;
};

} //end of namespace KRPC
